{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "model.schema.json",
  "title": "Model",
  "description": "Schema Model",
  "type": "object",
  "properties": {
    "coreVersion": {
      "description": "Core version",
      "type": "string",
      "enum": ["v1"]
    },
    "kind": {
      "description": "Model kind",
      "type": "string",
      "enum": ["Item", "ItemTemplate"]
    },
    "includeTemplates": {
      "description": "Included templates",
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "metadata": {
      "description": "Model metadata",
      "$ref": "#/definitions/Metadata"
    },
    "spec": {
      "description": "Item specification",
      "type": "object",
      "properties": {
        "attributes": {
          "description": "Item attributes",
          "type": "object",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "$ref": "#/definitions/Attribute"
          }
        },
        "indexes": {
          "description": "Item indexes. If the index name begins with _, it will be prefixed by the table name",
          "type": "object",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "$ref": "#/definitions/Index"
          }
        }
      },
      "additionalProperties": false
    }
  },
  "additionalProperties": false,
  "required": ["coreVersion", "kind", "metadata", "spec"],
  "definitions": {
    "Metadata": {
      "type": "object",
      "properties": {
        "name": {
          "description": "Item name (without whitespaces) starting with a lowercase character (required)",
          "type": "string",
          "minLength": 1,
          "maxLength": 50
        },
        "displayName": {
          "description": "Display name (optional, name is used by default)",
          "type": "string",
          "minLength": 1,
          "maxLength": 50
        },
        "pluralName": {
          "description": "Plural name (without whitespaces) starting with a lowercase character (required)",
          "type": "string",
          "minLength": 1,
          "maxLength": 50
        },
        "displayPluralName": {
          "description": "Display plural name (optional, pluralName is used by default)",
          "type": "string",
          "minLength": 1,
          "maxLength": 50
        },
        "titleAttribute": {
          "description": "Title attribute name (optional, 'id' is used by default)",
          "type": "string",
          "minLength": 1,
          "maxLength": 50
        },
        "dataSource": {
          "description": "Data source name (optional, 'main' is used by default)",
          "type": "string",
          "minLength": 1,
          "maxLength": 50
        },
        "tableName": {
          "description": "Table name (optional). Prefixes core_ and sec_ are not allowed",
          "type": "string",
          "minLength": 1,
          "maxLength": 50
        },
        "query": {
          "description": "SQL query (optional)",
          "type": "string",
          "minLength": 1
        },
        "cacheTtl": {
          "description": "Cache TTL in minutes (optional). If value is -1, the cache will be disabled",
          "type": "integer",
          "minimum": -1
        },
        "readOnly": {
          "description": "Read Only flag (optional, false by default)",
          "type": "boolean"
        },
        "description": {
          "description": "Description (optional, null by default)",
          "type": "string",
          "minLength": 1,
          "maxLength": 250
        },
        "icon": {
          "description": "Icon name (optional, null by default)",
          "type": "string",
          "minLength": 1,
          "maxLength": 50
        },
        "core": {
          "description": "Core flag (optional, false by default)",
          "type": "boolean"
        },
        "performDdl": {
          "description": "DDL operation performing flag (optional, true by default)",
          "type": "boolean"
        },
        "versioned": {
          "description": "Versioning flag (optional, false by default)",
          "type": "boolean"
        },
        "manualVersioning": {
          "description": "Manual versioning flag (optional, false by default)",
          "type": "boolean"
        },
        "localized": {
          "description": "Localization flag (optional, false by default)",
          "type": "boolean"
        },
        "revisionPolicy": {
          "description": "Revision policy ID (optional, null by default)",
          "type": "string"
        },
        "lifecycle": {
          "description": "Lifecycle ID (optional, null by default)",
          "type": "string"
        },
        "permission": {
          "description": "Permission ID (optional, Default Permission ID by default)",
          "type": "string"
        },
        "notLockable": {
          "description": "Disabling lock/unlock flag (optional, false by default)",
          "type": "boolean"
        },
        "implementation": {
          "description": "Implementation class (optional, null by default)",
          "type": "string"
        }
      },
      "additionalProperties": false,
      "required": ["name", "pluralName"]
    },
    "Attribute": {
      "type": "object",
      "properties": {
        "type": {
          "description": "Attribute type (required)",
          "type": "string",
          "enum": [
            "uuid", "string", "text", "enum", "sequence", "email", "password", "int", "long", "float", "double",
            "decimal", "date", "time", "datetime", "timestamp", "bool", "array", "json", "media", "relation"
          ]
        },
        "columnName": {
          "description": "Column name (optional, lowercase attribute name is used in database by default). Can be null for oneToMany and manyToMany relations",
          "type": "string",
          "minLength": 1,
          "maxLength": 50
        },
        "displayName": {
          "description": "Display name (required)",
          "type": "string",
          "minLength": 1,
          "maxLength": 50
        },
        "description": {
          "description": "Description (optional, null by default)",
          "type": "string",
          "minLength": 1,
          "maxLength": 250
        },
        "seqName": {
          "description": "Sequence name (required for sequence type)",
          "type": "string",
          "minLength": 1,
          "maxLength": 50
        },
        "enumSet": {
          "description": "Enumeration entries (required for enum type)",
          "type": "array",
          "items": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50
          },
          "minItems": 1
        },
        "confirm": {
          "description": "Password confirmation (in UI) flag (optional, used only for password type)",
          "type": "boolean"
        },
        "encode": {
          "description": "Password encoding flag (optional, true by default, used only for password type)",
          "type": "boolean"
        },
        "relType": {
          "description": "Relation type (required for relation type)",
          "type": "string",
          "enum": ["oneToOne", "manyToOne", "oneToMany", "manyToMany"]
        },
        "target": {
          "description": "Target item name (required for relation type)",
          "type": "string",
          "minLength": 1,
          "maxLength": 50
        },
        "intermediate": {
          "description": "Intermediate item name (required for manyToMany relation type). Intermediate item includes source and target attributes",
          "type": "string",
          "minLength": 1,
          "maxLength": 50
        },
        "mappedBy": {
          "description": "In bidirectional relations, the owning side declares the inversedBy key while the inversed side declares the mappedBy key",
          "type": "string",
          "minLength": 1,
          "maxLength": 50
        },
        "inversedBy": {
          "description": "In bidirectional relations, the owning side declares the inversedBy key while the inversed side declares the mappedBy key",
          "type": "string",
          "minLength": 1,
          "maxLength": 50
        },
        "keyed": {
          "description": "Primary key flag (used only for id attribute)",
          "type": "boolean"
        },
        "required": {
          "description": "Mandatory flag (optional, false by default)",
          "type": "boolean"
        },
        "defaultValue": {
          "description": "Default value (optional, null by default)",
          "type": ["string", "number", "boolean"],
          "minLength": 1,
          "maxLength": 50
        },
        "unique": {
          "description": "Uniqueness flag (optional, false by default). Additional columns may be added to the unique index depending on configuration parameters (versioning.include-in-unique-index and i18n.include-in-unique-index) and attributes (versioned and localized). If other logic is needed, use the indexes section",
          "type": "boolean"
        },
        "indexed": {
          "description": "Uniqueness flag (optional, false by default). For versioned or localized item non-unique index can be added on par with a composite unique index",
          "type": "boolean"
        },
        "private": {
          "description": "Privacy flag (optional, false by default)",
          "type": "boolean"
        },
        "readOnly": {
          "description": "Read only flag",
          "type": "boolean"
        },
        "pattern": {
          "description": "Regex pattern (optional, null by default). For string type",
          "type": "string",
          "minLength": 1,
          "maxLength": 50
        },
        "length": {
          "description": "String length (optional, null by default). For string type",
          "type": "integer",
          "minimum": 1
        },
        "precision": {
          "description": "Precision (optional, null by default). For decimal type",
          "type": "integer",
          "minimum": 0
        },
        "scale": {
          "description": "Scale (optional, null by default). For decimal type",
          "type": "integer",
          "minimum": 0
        },
        "minRange": {
          "description": "Minimum range (optional, null by default). For int, long, float, double and decimal types",
          "type": "number"
        },
        "maxRange": {
          "description": "Maximum range (optional, null by default). For int, long, float, double and decimal types",
          "type": "number"
        },
        "colHidden": {
          "description": "Hide column in UI table (optional, null by default)",
          "type": "boolean"
        },
        "colWidth": {
          "description": "Column width in UI table, px (optional, null by default)",
          "type": "integer",
          "minimum": 1
        },
        "fieldHidden": {
          "description": "Hide field in UI form (optional, null by default)",
          "type": "boolean"
        },
        "fieldWidth": {
          "description": "Field width in UI form, colspan (optional, null by default)",
          "type": "integer",
          "minimum": 1,
          "maximum": 24
        }
      },
      "additionalProperties": false,
      "required": ["type", "displayName"]
    },
    "Index": {
      "type": "object",
      "properties": {
        "columns": {
          "description": "Index columns. The index will be created with the specified columns only (without additional version or locale columns)",
          "type": "array",
          "items": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50
          },
          "minItems": 1
        },
        "unique": {
          "description": "Uniqueness flag (optional, false by default)",
          "type": "boolean"
        }
      },
      "additionalProperties": false,
      "required": ["columns"]
    }
  }
}